home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / od-macos / mac.c < prev    next >
C/C++ Source or Header  |  1998-01-20  |  43KB  |  1,672 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * Mac port specific stuff
  5.   * 
  6.   * (c) 1996 Ernesto Corvi
  7.   */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <QDOffscreen.h>
  13. #include <Palettes.h>
  14. #include <Profiler.h>
  15. #include <Sound.h>
  16. #include <errno.h>
  17.  
  18. #include "mackbd.h"
  19. #include "config.h"
  20. #include "threaddep/penguin.h"
  21. #include "uae.h"
  22. #include "amiga.h"
  23. #include "options.h"
  24. #include "memory.h"
  25. #include "custom.h"
  26. #include "newcpu.h"
  27. #include "xwin.h"
  28. #include "keyboard.h"
  29. #include "keybuf.h"
  30.  
  31. #define kAppleMenuID    128
  32. #define kFileMenuID        129
  33. #define    kEditMenuID        130
  34. #define    kDrivesMenuID    131
  35. #define    kMemoryMenuID    132
  36. #define    kResMenuID        135
  37. #define    kRateMenuID        134
  38. #define    kVideoMenuID    133
  39.  
  40. #define kAboutDialogID    128
  41. #define kHardfileDialogID    129
  42. #define kQuitError 130
  43.  
  44. #define mTopLeft(r)        (((Point *)&(r))[0])
  45. #define mBotRight(r)    (((Point *)&(r))[1])
  46.  
  47. #define qd_CenterScreen 144
  48.  
  49. static GDHandle curDevice;
  50. static int oldDepth=0;
  51. static Boolean macCursorState=true;
  52. int    use_quickdraw=true;
  53. short    filesys_vRefNum=0;
  54. static KeyMap keys;
  55. static Boolean redraw=true,diskInit=true;
  56. static int mBarState=1;
  57. static int RM=0;
  58. static int my_use_gfxlib=0;
  59. static int my_automount_uaedev=1;
  60. static int my_screen_res=3;
  61. static int my_use_quickdraw=1;
  62. static WindowPtr mywin;
  63. static RgnHandle gOldVisRgn;
  64. static short gOldMBarHeight;
  65. static Boolean    macDiskStatus[4];
  66. static GWorldPtr gOffscreenBuffer;
  67. static PixMapHandle gOffscreenPixels;
  68. static Rect gOffscreenRect,gDrawRect;    
  69. static unsigned char *gOffscreenBaseAddr;
  70. static unsigned long gOffscreenRowBytes;
  71. static PaletteHandle mypal;
  72. static int CenterScreen=0;
  73. static CTabHandle    myCTAB;
  74. static long screenH=0,screenV=0;
  75. static GrafPtr    dummyPort;
  76. extern SndChannelPtr newChannel;
  77. static unsigned long refresh;
  78. extern char *xlinebuffer;
  79.  
  80.  /* Keyboard and mouse */
  81.  
  82. static int keystate[256];
  83.  
  84. static int colors_allocated;
  85.  
  86. // Prototypes
  87. static void HandleMenu (long mSelect);
  88. static void macHandleCursors(void);
  89. static Boolean CheckForSetup (void);
  90. static void ParamAString( ConstStr255Param theStr);
  91. static void printStatusLine (void);
  92. static void Share_main(void);
  93. static void Share_ResolvePath (FSSpec *fSpec, char *path);
  94. // end Prototypes
  95.  
  96. static void my_setpalette(int count, int r, int g, int b)
  97. {    RGBColor mycolor;
  98.     
  99.     mycolor.red=r*1024;
  100.     mycolor.green=g*1024;
  101.     mycolor.blue=b*1024;
  102.     
  103.     if (count == 0 || count == 255) SetEntryColor(mypal, count, &mycolor);
  104.     else SetEntryColor(mypal, (~count & 0x000000ff), &mycolor);
  105. }
  106.  
  107. static int get_color(int r, int g, int b, xcolnr *cnp)
  108. {
  109.     if (colors_allocated == 256) return -1;
  110.     *cnp = colors_allocated;
  111.     my_setpalette(colors_allocated, doMask(r, 6, 0), doMask(g, 6, 0), doMask(b, 6, 0));
  112.     colors_allocated++;
  113.     return 1;
  114. }
  115.  
  116. static void init_colors(void)
  117. {
  118.     int rw = 5, gw = 5, bw = 5;
  119.     colors_allocated = 0;
  120.     
  121.     if (gfxvidinfo.pixbytes == 1)
  122.     alloc_colors256(get_color);
  123.     else
  124.     {    if (gfxvidinfo.pixbytes == 4) rw=gw=bw=8;
  125.         alloc_colors64k(rw, gw, bw, gw+bw, bw, 0);
  126.     }
  127. }
  128.  
  129. static void HideMenuBar(GrafPtr grafPort)
  130. {    Rect    menuRect={0,0,20,640};
  131.     RgnHandle newVisRgn;
  132.     GrafPtr savePort;
  133.     
  134.     GetPort(&savePort);
  135.     SetPort(grafPort);
  136.  
  137.         // save off vis region
  138.     gOldVisRgn = NewRgn();
  139.     CopyRgn(grafPort->visRgn, gOldVisRgn);
  140.  
  141.         // expand the vis region to the port rect
  142.     newVisRgn = NewRgn();
  143.     RectRgn(newVisRgn, &grafPort->portRect);
  144.     CopyRgn(newVisRgn, grafPort->visRgn);
  145.     DisposeRgn(newVisRgn);
  146.  
  147.     PaintRect(&menuRect);
  148.  
  149.     gOldMBarHeight = GetMBarHeight();
  150.     LMSetMBarHeight(0);
  151.     
  152.     SetPort(savePort);
  153. }
  154.  
  155. static void ShowMenuBar(GrafPtr grafPort)
  156. {
  157.     GrafPtr savePort;
  158.     RgnHandle junkRgn;
  159.  
  160.     GetPort(&savePort);
  161.     SetPort(grafPort);
  162.  
  163.         // fill the rounded corners of the screen with black again
  164.     junkRgn = NewRgn();
  165.     CopyRgn(gOldVisRgn, junkRgn);
  166.     DiffRgn(grafPort->visRgn, junkRgn, junkRgn);
  167.  
  168.     #ifdef dangerousPattern
  169.     FillRgn(junkRgn, qd.black);
  170.     #else
  171.     FillRgn(junkRgn, &qd.black);
  172.     #endif
  173.  
  174.     DisposeRgn(junkRgn);
  175.  
  176.         // restore the old vis region
  177.     CopyRgn(gOldVisRgn, grafPort->visRgn);
  178.     DisposeRgn(gOldVisRgn);
  179.     gOldVisRgn = NULL;
  180.     
  181.     LMSetMBarHeight(gOldMBarHeight);
  182.     
  183.     DrawMenuBar();
  184. }
  185.  
  186. int graphics_init()
  187. {
  188.     int i;
  189.     char p1;
  190.     long tmp;
  191.     long memtop=0;
  192.     Rect    windowRectangle,osRect={0,0,600,800};
  193.     char *dst;
  194.     CGrafPtr oldPort;
  195.     GDHandle oldDevice;
  196.     
  197.     my_use_gfxlib=use_gfxlib;
  198.     my_automount_uaedev=automount_uaedev;
  199.     my_screen_res=screen_res;
  200.     my_use_quickdraw=use_quickdraw;
  201.     
  202.     if (CheckForSetup()) ExitToShell();
  203.     
  204.     gfxvidinfo.maxblocklines=600; // Whatever...
  205.     
  206.     if (gfxvidinfo.pixbytes == 1)
  207.     {    myCTAB=GetCTable(128);
  208.         mypal=NewPalette(256, myCTAB, pmTolerant + pmExplicit, 0x0000);
  209.     }
  210.     
  211.     windowRectangle.left=0;
  212.     if (screen_res > 4 || screen_res < 0) screen_res=3;
  213.     if (screen_res == 4 || screen_res == 2) dont_want_aspect = 0;
  214.     else dont_want_aspect = 1;
  215.     switch (screen_res)
  216.     {    case 0:
  217.         case 1:
  218.         case 2:
  219.             CenterScreen=(36*gfxvidinfo.pixbytes)/2;
  220.             windowRectangle.right=320;
  221.             use_lores = 1;
  222.             windowRectangle.top=40;
  223.             if (screen_res == 0) windowRectangle.bottom=200+windowRectangle.top+38;
  224.             else if (screen_res == 1) windowRectangle.bottom=256+windowRectangle.top+38;
  225.                  else windowRectangle.bottom=400+windowRectangle.top+38;
  226.         break;
  227.     
  228.         case 3:
  229.         case 4:
  230.             CenterScreen=36*gfxvidinfo.pixbytes;
  231.             use_lores = 0;
  232.             windowRectangle.right=640;
  233.             if (dont_want_aspect == 0)
  234.             {    windowRectangle.top=0;
  235.                 windowRectangle.bottom=480;
  236.             }
  237.             else
  238.             {    windowRectangle.top=40;
  239.                 windowRectangle.bottom=256+windowRectangle.top+38;
  240.             }
  241.         break;
  242.     }
  243.     
  244.     screenV=windowRectangle.bottom-windowRectangle.top;
  245.     if (dont_want_aspect == 1 || screen_res == 2) screenV -= 12;
  246.     screenH=windowRectangle.right-windowRectangle.left;
  247.     
  248.     mywin = NewCWindow(nil, &windowRectangle, "\pThe Un*x Amiga Emulator", 1, 4, (WindowPtr)-1L, 0, 0);
  249.     SetPort(mywin);
  250.     
  251.     gui_prepare_leds(screenV);
  252.     
  253.     init_colors();
  254.     
  255.     if (use_quickdraw)
  256.     {    GetGWorld(&oldPort, &oldDevice);
  257.         NewGWorld( &gOffscreenBuffer, (gfxvidinfo.pixbytes*8), &osRect, 0L, oldDevice, 0);
  258.         SetGWorld(oldPort, oldDevice);
  259.         gOffscreenPixels = GetGWorldPixMap( gOffscreenBuffer );
  260.         LockPixels(gOffscreenPixels);
  261.         gDrawRect.top=(mywin->portRect).top;
  262.         gDrawRect.left=(mywin->portRect).left;
  263.         gDrawRect.right=(mywin->portRect).right;
  264.         gDrawRect.bottom=(mywin->portRect).bottom;
  265.         gDrawRect.bottom -= 12;
  266.         gOffscreenRect.top=(mywin->portRect).top;
  267.         gOffscreenRect.left=(mywin->portRect).left;
  268.         gOffscreenRect.right=(mywin->portRect).right;
  269.         gOffscreenRect.bottom=(mywin->portRect).bottom;
  270.         gOffscreenRect.bottom -= 12;
  271.         OffsetRect(&gOffscreenRect,(use_lores == 1) ? qd_CenterScreen/2 : qd_CenterScreen,0);
  272.         gOffscreenBaseAddr = (unsigned char *)GetPixBaseAddr(gOffscreenPixels);
  273.         gOffscreenRowBytes = (*gOffscreenPixels)->rowBytes & 0x3fff;
  274.         gfxvidinfo.bufmem=(char *)gOffscreenBaseAddr;
  275.         gfxvidinfo.rowbytes=gOffscreenRowBytes;
  276.         SetGWorld(gOffscreenBuffer, NULL);
  277.         PaintRect(&gOffscreenRect);
  278.         SetGWorld(oldPort, oldDevice);
  279.     }
  280.     else
  281.     {    gfxvidinfo.bufmem=NewPtrClear(600*(800*gfxvidinfo.pixbytes));
  282.         if (gfxvidinfo.bufmem == 0) SysBeep(0);
  283.         gfxvidinfo.rowbytes=800*gfxvidinfo.pixbytes;
  284.     }
  285.     
  286.     if (dont_want_aspect || screen_res == 2) printStatusLine();
  287.     
  288.     if (gfxvidinfo.pixbytes == 1)
  289.     {    SetPalette((WindowPtr) -1L, mypal, false);
  290.     }
  291.     
  292.     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
  293.     for(i=0; i<256; i++) keystate[i] = 0;
  294.     
  295.     lastmx = lastmy = 0; newmousecounters=0;
  296.     
  297.     refresh=TickCount();
  298.     
  299. //    tmp=ProfilerInit(collectDetailed,bestTimeBase,200,10);
  300.     return 1;
  301. }
  302.  
  303. void graphics_leave()
  304. {
  305. //    ProfilerDump((unsigned char *)"\pmyProf");
  306. //    ProfilerTerm();
  307.  
  308.     ShowCursor();
  309.     if (dont_want_aspect == 0) if (!mBarState) ShowMenuBar(mywin);
  310.     if (oldDepth != 0) SetDepth(curDevice,oldDepth,0,0);
  311.     FlushEvents (everyEvent,0);
  312.     SndDisposeChannel(newChannel,true);
  313.     if (gfxvidinfo.pixbytes == 1)
  314.     {    DisposePalette(mypal);
  315.         DisposeCTable(myCTAB);
  316.     }
  317.     DisposeWindow(mywin);
  318.     if (use_quickdraw)
  319.     {    DisposeGWorld(gOffscreenBuffer);
  320.     }
  321.     else DisposePtr((Ptr)(gfxvidinfo.bufmem));
  322. }
  323.  
  324. static int next_line_double;
  325. static int next_line_pos = 0;
  326.  
  327. void flush_screen ()
  328. {    short    y,x,y1=0;
  329.     unsigned char *winbaseaddr;
  330.     long *src,*dest;
  331.     unsigned long winrowbytes;
  332.     PixMapHandle    ph;
  333.     CGrafPtr    oldPort;
  334.     GDHandle oldDevice;
  335.  
  336.     if (TickCount() < refresh + 4) return;
  337.     if (!redraw) return;
  338.     if (FrontWindow() != mywin) return;
  339.     if (inhibit_frame) return;
  340.        
  341.        GetGWorld(&oldPort,&oldDevice);
  342.     SetGWorld((CWindowPtr) mywin, oldDevice);
  343.     if (use_quickdraw)
  344.     {    ForeColor(blackColor);    /* Prevents colorizing mode */
  345.         BackColor(whiteColor);    /* Prevents colorizing mode */
  346.         (*((*gOffscreenPixels)->pmTable))->ctSeed = (*((*((*(GetGDevice()))->gdPMap))->pmTable))->ctSeed;
  347.         CopyBits((BitMap *)(*gOffscreenPixels), &(mywin->portBits), &gOffscreenRect, &gDrawRect, srcCopy, (RgnHandle) 0L);
  348.     }
  349.     else
  350.     {    ph=GetGWorldPixMap((CGrafPort *) mywin);
  351.         winbaseaddr=( unsigned char *) GetPixBaseAddr(ph);
  352.         winrowbytes=(*ph)->rowBytes & 0x3FFF;
  353.         winbaseaddr-=((**ph).bounds.left);
  354.         winbaseaddr-=(((**ph).bounds.top)*winrowbytes);
  355.         dest=(long *)winbaseaddr;
  356.         src=(long *)(gfxvidinfo.bufmem)+CenterScreen;
  357.         
  358.         y=0;
  359.         if ((dont_want_aspect == 0 && mBarState == true && y < 20)) y=20;
  360.         dest=(long *)(winbaseaddr+(y*winrowbytes));
  361.         src=(long *)(gfxvidinfo.bufmem+(y*gfxvidinfo.rowbytes))+CenterScreen;
  362.         for (; y< screenV; y++)
  363.         {    for (x=0;x < ((screenH*gfxvidinfo.pixbytes)/sizeof(long));x++) *dest++ = *src++;
  364.         dest=(long *)(winbaseaddr+(y*winrowbytes));
  365.         src=(long *)(gfxvidinfo.bufmem+(y*gfxvidinfo.rowbytes))+CenterScreen;
  366.         }
  367.     }
  368.     SetGWorld(oldPort, oldDevice);
  369. }
  370.  
  371. void flush_block (int start_y, int end_y)
  372. {    short    y,x,y1=0;
  373.     unsigned char *winbaseaddr;
  374.     long *src,*dest;
  375.     unsigned long winrowbytes;
  376.     PixMapHandle    ph;
  377.     Rect            srcRect,dstRect;
  378.     CGrafPtr    oldPort;
  379.     GDHandle oldDevice;
  380.  
  381.     if (TickCount() < refresh + 4) return;
  382.     if (!redraw) return;
  383.     if (FrontWindow() != mywin) return;
  384.     if (inhibit_frame) return;
  385.        
  386.        if (end_y > screenV) end_y=screenV;
  387.        GetGWorld(&oldPort,&oldDevice);
  388.     SetGWorld((CWindowPtr) mywin, oldDevice);
  389.     if (use_quickdraw)
  390.     {    
  391.         srcRect.top=start_y;
  392.         srcRect.bottom=end_y;
  393.         srcRect.left=gOffscreenRect.left;
  394.         srcRect.right=gOffscreenRect.right;
  395.         dstRect.top=start_y;
  396.         dstRect.bottom=end_y;
  397.         dstRect.left=gDrawRect.left;
  398.         dstRect.right=gDrawRect.right;
  399.         
  400.         /* Taken from my favorite book:
  401.            "It is significant, if not surprising, that the Mac and PC cannot come
  402.            to an agreement over the most fundamental issue in the universe: the
  403.            distinction between black and white. On the PC, the pixel value 0
  404.            indicates a pixel of zero intensity, or black. On the Mac, 0 indicates
  405.            a page wich has not been written on, wich leaves it white."
  406.            
  407.                                                    Eric Johnston.
  408.                                        Tricks of the Mac Game Programming Gurus.
  409.         
  410.         Check set_palette and line_to_scr8() on how i fixed that.
  411.         If you know a better way let me know.
  412.         */
  413.         
  414.         ForeColor(blackColor);    /* Prevents colorizing mode */
  415.         BackColor(whiteColor);    /* Prevents colorizing mode */
  416.         (*((*gOffscreenPixels)->pmTable))->ctSeed = (*((*((*(GetGDevice()))->gdPMap))->pmTable))->ctSeed;
  417.         CopyBits((BitMap *)(*gOffscreenPixels), &(mywin->portBits), &srcRect, &dstRect, srcCopy, (RgnHandle) 0L);
  418.     }
  419.     else
  420.     {    ph=GetGWorldPixMap((CGrafPort *) mywin);
  421.         winbaseaddr=( unsigned char *) GetPixBaseAddr(ph);
  422.         winrowbytes=(*ph)->rowBytes & 0x3FFF;
  423.         winbaseaddr-=((**ph).bounds.left);
  424.         winbaseaddr-=(((**ph).bounds.top)*winrowbytes);
  425.         dest=(long *)winbaseaddr;
  426.         src=(long *)(gfxvidinfo.bufmem)+CenterScreen;
  427.         
  428.         y=start_y;
  429.         if ((dont_want_aspect == 0 && mBarState == true && y < 20)) y=20;
  430.         dest=(long *)(winbaseaddr+(y*winrowbytes));
  431.         src=(long *)(gfxvidinfo.bufmem+(y*gfxvidinfo.rowbytes))+CenterScreen;
  432.         for (; y <= end_y; y++)
  433.         {    for (x=0;x < ((screenH*gfxvidinfo.pixbytes)/sizeof(long));x++) *dest++ = *src++;
  434.         dest=(long *)(winbaseaddr+(y*winrowbytes));
  435.         src=(long *)(gfxvidinfo.bufmem+(y*gfxvidinfo.rowbytes))+CenterScreen;
  436.         }
  437.     }
  438.     SetGWorld(oldPort, oldDevice);
  439. }
  440.  
  441. void flush_line(int line_num)
  442. {
  443.     long i;
  444.     char *dst,*src;
  445.     CGrafPtr oldPort;
  446.     GDHandle oldDevice;
  447.      
  448.     if (use_quickdraw)
  449.     {    GetGWorld(&oldPort, &oldDevice);
  450.         SetGWorld(gOffscreenBuffer, NULL);
  451.         dst=(char *)gOffscreenBaseAddr;
  452.         dst+=(char *)((line_num)*gOffscreenRowBytes);
  453.         src=(char *)xlinebuffer;
  454.         BlockMove(src,dst,gOffscreenRowBytes);
  455.         if (next_line_double)
  456.         {    dst=(char *)gOffscreenBaseAddr;
  457.             dst+=(char *)((line_num+1)*gOffscreenRowBytes);
  458.             src=(char *)xlinebuffer;
  459.             BlockMove(src,dst,gOffscreenRowBytes);
  460.         }
  461.         SetGWorld(oldPort, oldDevice);
  462.     }
  463.     else
  464.     {    if (line_num < 481)
  465.         {    dst=(char *)gfxvidinfo.bufmem+((line_num)*gfxvidinfo.rowbytes);
  466.             src=(char *)xlinebuffer;
  467.             BlockMove(src,dst,gfxvidinfo.rowbytes);
  468.         }
  469.         if (next_line_double)
  470.         {    
  471.             if (line_num < 481)
  472.             {   dst=(char *)gfxvidinfo.bufmem+((line_num+1)*gfxvidinfo.rowbytes);
  473.                 src=(char *)xlinebuffer;
  474.             BlockMove(src,dst,gfxvidinfo.rowbytes);
  475.             }
  476.         }
  477.     }
  478. }
  479.  
  480. /* Decode KeySyms. This function knows about all keys that are common 
  481.  * between different keyboard languages.
  482.  */
  483. static int kc_decode (long ks)
  484. {    
  485.     switch (ks)
  486.     {
  487.      case kAKeyMap: return AK_A;
  488.      case kBKeyMap: return AK_B;
  489.      case kCKeyMap: return AK_C;
  490.      case kDKeyMap: return AK_D;
  491.      case kEKeyMap: return AK_E;
  492.      case kFKeyMap: return AK_F;
  493.      case kGKeyMap: return AK_G;
  494.      case kHKeyMap: return AK_H;
  495.      case kIKeyMap: return AK_I;
  496.      case kJKeyMap: return AK_J;
  497.      case kKKeyMap: return AK_K;
  498.      case kLKeyMap: return AK_L;
  499.      case kMKeyMap: return AK_M;
  500.      case kNKeyMap: return AK_N;
  501.      case kOKeyMap: return AK_O;
  502.      case kPKeyMap: return AK_P;
  503.      case kQKeyMap: return AK_Q;
  504.      case kRKeyMap: return AK_R;
  505.      case kSKeyMap: return AK_S;
  506.      case kTKeyMap: return AK_T;
  507.      case kUKeyMap: return AK_U;
  508.      case kVKeyMap: return AK_V;
  509.      case kWKeyMap: return AK_W;
  510.      case kXKeyMap: return AK_X;
  511.      
  512.      case k0KeyMap: return AK_0;
  513.      case k1KeyMap: return AK_1;
  514.      case k2KeyMap: return AK_2;
  515.      case k3KeyMap: return AK_3;
  516.      case k4KeyMap: return AK_4;
  517.      case k5KeyMap: return AK_5;
  518.      case k6KeyMap: return AK_6;
  519.      case k7KeyMap: return AK_7;
  520.      case k8KeyMap: return AK_8;
  521.      case k9KeyMap: return AK_9;
  522.      
  523.      case kKP0KeyMap: return AK_NP0;
  524.      case kKP1KeyMap: return AK_NP1;
  525.      case kKP2KeyMap: return AK_NP2;
  526.      case kKP3KeyMap: return AK_NP3;
  527.      case kKP4KeyMap: return AK_NP4;
  528.      case kKP5KeyMap: return AK_NP5;
  529.      case kKP6KeyMap: return AK_NP6;
  530.      case kKP7KeyMap: return AK_NP7;
  531.      case kKP8KeyMap: return AK_NP8;
  532.      case kKP9KeyMap: return AK_NP9;
  533.     
  534.      case kF1KeyMap: return AK_F1;
  535.      case kF2KeyMap: return AK_F2;
  536.      case kF3KeyMap: return AK_F3;
  537.      case kF4KeyMap: return AK_F4;
  538.      case kF5KeyMap: return AK_F5;
  539.      case kF6KeyMap: return AK_F6;
  540.      case kF7KeyMap: return AK_F7;
  541.      case kF8KeyMap: return AK_F8;
  542.      case kF9KeyMap: return AK_F9;
  543.      case kF10KeyMap: return AK_F10;
  544.     
  545.      case kBackSpaceKeyMap: return AK_BS;
  546.      case kTabKeyMap: return AK_TAB;
  547.      case kReturnKeyMap: return AK_RET;
  548.      case kEscapeKeyMap: return AK_ESC;
  549.      
  550.      case kSpaceBarMap:  return AK_SPC;
  551.      
  552.      case kUpArrowKeyMap: return AK_UP;
  553.      case kDownArrowKeyMap: return AK_DN;
  554.      case kLeftArrowKeyMap: return AK_LF;
  555.      case kRightArrowKeyMap: return AK_RT;
  556.     
  557.      case kF11KeyMap: return AK_inhibit;
  558.  
  559.      case kF12KeyMap: return AK_mousestuff;
  560.  
  561.      case kPgUpKeyMap: return AK_RAMI;
  562.      case kPgDnKeyMap: return AK_LAMI;
  563.      case kBackSlash: return AK_BACKSLASH;
  564.     }
  565.     return -1;
  566. }
  567.  
  568. static int decode_us(long ks)
  569. {
  570.     switch(ks) {
  571.     /* US specific */
  572.  
  573.      case kYKeyMap: return AK_Y;
  574.      case kZKeyMap: return AK_Z;
  575.      case kLBracketKeyMap: return AK_LBRACKET;
  576.      case kRBracketKeyMap: return AK_RBRACKET;
  577.      case kCommaKeyMap: return AK_COMMA;
  578.      case kPeriodKeyMap: return AK_PERIOD;
  579.      case kSlashKeyMap: return AK_SLASH;
  580.      case kSemiColonKeyMap: return AK_SEMICOLON;
  581.      case kMinusKeyMap: return AK_MINUS;
  582.      case kEqualKeyMap: return AK_EQUAL;
  583.      case kQuoteKeyMap: return AK_QUOTE;
  584.     }
  585.  
  586.     return -1;
  587. }
  588.  
  589. static int decode_de(long ks)
  590. {
  591.     switch(ks) {
  592. /* DE specific
  593.      case XK_Y: case XK_y: return AK_Z;
  594.      case XK_Z: case XK_z: return AK_Y;
  595.      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
  596.      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
  597.      case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
  598.      case XK_plus: case XK_asterisk: return AK_RBRACKET;
  599.      case XK_comma: return AK_COMMA;
  600.      case XK_period: return AK_PERIOD;
  601.      case XK_less: case XK_greater: return AK_LTGT;
  602.      case XK_numbersign: return AK_NUMBERSIGN;
  603.      case XK_ssharp: return AK_MINUS;
  604.      case XK_apostrophe: return AK_EQUAL;
  605.      case XK_asciicircum: return AK_00;
  606.      case XK_minus: return AK_SLASH;        
  607. */
  608.     }
  609.  
  610.     return -1;
  611. }
  612.  
  613. static int keycode2amiga(long code)
  614. {
  615.     long ks;
  616.     int as;
  617.     
  618.     ks = (code & keyCodeMask) >> 8;
  619.     as = kc_decode (ks);
  620.     
  621.     if (as == -1) {        
  622.     switch(keyboard_lang) {
  623.      case KBD_LANG_US:
  624.         as = decode_us(ks);
  625.         break;
  626.         
  627.      case KBD_LANG_DE:
  628.         as = decode_de(ks);
  629.         break;
  630.         
  631.      default:
  632.         as = -1;
  633.         break;
  634.     }
  635.     }
  636.     if(-1 != as)
  637.     return as;
  638.     return -1;
  639. }
  640.  
  641. void handle_events()
  642. {    WindowPeek    wp;
  643.     short        windowPart;
  644.     Boolean repeat;
  645.     Boolean itHappened;
  646.     Point   mpos;
  647.     EventRecord event;
  648.     int kc,i,count;
  649.     char    osKind;
  650.     GrafPtr    oldSave;
  651.     
  652.     GetPort(&oldSave);
  653.     if ((redraw) && mywin != FrontWindow()) SelectWindow(mywin);
  654.     
  655.     SetEventMask(-1);
  656.     
  657.     if (diskInit)
  658.     {    macDiskStatus[0]=!disk_empty(0);
  659.         SetMenuItemText(GetMenuHandle(kDrivesMenuID), 1, macDiskStatus[0] ? "\pEject Disk in DF0:" : "\pInsert Disk in DF0:");
  660.         macDiskStatus[1]=!disk_empty(1);
  661.         SetMenuItemText(GetMenuHandle(kDrivesMenuID), 2, macDiskStatus[1] ? "\pEject Disk in DF1:" : "\pInsert Disk in DF1:");
  662.         macDiskStatus[2]=!disk_empty(2);
  663.         SetMenuItemText(GetMenuHandle(kDrivesMenuID), 3, macDiskStatus[2] ? "\pEject Disk in DF2:" : "\pInsert Disk in DF2:");
  664.         macDiskStatus[3]=!disk_empty(3);
  665.         SetMenuItemText(GetMenuHandle(kDrivesMenuID), 4, macDiskStatus[3] ? "\pEject Disk in DF3:" : "\pInsert Disk in DF3:");
  666.         diskInit=false;
  667.     }
  668.     
  669.     if (redraw)
  670.     {    gui_update_leds();
  671.         macHandleCursors();
  672.     }
  673.     
  674.     GetKeys(keys);
  675.     if (BitTst(&keys, kCommandRawKey))
  676.     buttonstate[2] = 1;
  677.     else
  678.     buttonstate[2] = 0;
  679.     
  680.     if (BitTst(&keys, kShiftRawKey))
  681.     {    
  682.     if (!keystate[AK_LSH]) {
  683.         keystate[AK_LSH] = 1;
  684.         record_key (AK_LSH << 1);
  685.         goto label1;
  686.     }
  687.     } else {
  688.     if (keystate[AK_LSH]) {
  689.         keystate[AK_LSH] = 0;
  690.         record_key ((AK_LSH << 1) | 1);
  691.         goto label1;
  692.     }
  693.     }
  694.     if (BitTst(&keys, kControlRawKey))
  695.     {    
  696.     if (!keystate[AK_CTRL]) {
  697.         keystate[AK_CTRL] = 1;
  698.         record_key (AK_CTRL << 1);
  699.         goto label1;
  700.     }
  701.     } else {    
  702.     if (keystate[AK_CTRL]) {
  703.         keystate[AK_CTRL] = 0;
  704.         record_key ((AK_CTRL << 1) | 1);
  705.         goto label1;
  706.     }
  707.     }
  708.     if (BitTst(&keys, kCapsRawKey))
  709.     {    
  710.     if (!keystate[AK_CAPSLOCK]) {
  711.         keystate[AK_CAPSLOCK] = 1;
  712.         record_key (AK_CAPSLOCK << 1);
  713.         goto label1;
  714.     }
  715.     } else {
  716.     if (keystate[AK_CAPSLOCK]) {
  717.         keystate[AK_CAPSLOCK] = 0;
  718.         record_key ((AK_CAPSLOCK << 1) | 1);
  719.         goto label1;
  720.     }
  721.     }
  722.     if (BitTst(&keys, kOptionRawKey))
  723.     {    
  724.     if (!keystate[AK_LALT]) {
  725.         keystate[AK_LALT] = 1;
  726.         record_key (AK_LALT << 1);
  727.         goto label1;
  728.     }
  729.     } else {
  730.     if (keystate[AK_LALT]) {
  731.         keystate[AK_LALT] = 0;
  732.         record_key ((AK_LALT << 1) | 1);
  733.         goto label1;
  734.     }
  735.     }
  736.     do {
  737.     repeat = 0;
  738.     newmousecounters=0;
  739.     itHappened=WaitNextEvent(-1,&event,0L,(*mywin).visRgn);
  740.  
  741.     switch(event.what) {
  742.      case keyDown:
  743.      case autoKey: {
  744.           if ((event.modifiers & cmdKey) != 0)
  745.           {    HandleMenu(MenuKey((char) (event.message & charCodeMask)));
  746.           }
  747.           else
  748.           {    int kc = keycode2amiga(event.message);
  749.              if (kc == -1) break;
  750.              switch (kc)
  751.              {    case AK_mousestuff:
  752.                      togglemouse();
  753.                       break;
  754.         
  755.                 case AK_inhibit:
  756.                       inhibit_frame ^= 1;
  757.                       break;
  758.         
  759.                 default:
  760.                       if (!keystate[kc])
  761.                       {     keystate[kc] = 1;
  762.                          record_key (kc << 1);
  763.                       }
  764.                       break;
  765.              }
  766.         }
  767.          break;
  768.      }
  769.      case keyUp: {
  770.          kc = keycode2amiga(event.message);
  771.          if (kc == -1) break;
  772.          keystate[kc] = 0;
  773.          record_key ((kc << 1) | 1);
  774.          break;
  775.      }
  776.      case mouseDown:
  777.          windowPart = FindWindow (event.where, (WindowPtr*) &wp);
  778.          if (windowPart == inMenuBar) HandleMenu(MenuSelect(event.where));
  779.          else
  780.          if (windowPart == inSysWindow) SystemClick (&event, (WindowPtr) wp);
  781.         else buttonstate[0] = 1;
  782.         break;
  783.          
  784.      case osEvt:
  785.          osKind=(event.message) >> 24;
  786.          if (osKind == suspendResumeMessage)
  787.          {    osKind=(event.message)&1;
  788.              if (osKind)
  789.              {    redraw=true; // Resume
  790.                  flush_screen();
  791.                  if (dont_want_aspect || screen_res == 2)
  792.                 {    SelectWindow(mywin);
  793.                     printStatusLine();
  794.                 }
  795.             }
  796.              else redraw=false; // Suspend
  797.          }
  798.          break;
  799.      case mouseUp:
  800.         buttonstate[0] = 0;
  801.         buttonstate[2] = 0;
  802.         break;
  803.     }
  804.     if (redraw)
  805.     {    GetMouse(&mpos);
  806.         if (mpos.h != lastmx) { lastmx=mpos.h; /* repeat = 1;*/ }
  807.         if (mpos.v != lastmy) { lastmy=mpos.v; /*repeat = 1;*/ }
  808.     }
  809.     } while (repeat);
  810.     
  811. label1:
  812.     /* "Affengriff" */
  813.     if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
  814.         m68k_reset();
  815.     SetPort(oldSave);
  816. }
  817.  
  818. int debuggable()
  819. {
  820.     return 1;
  821. }
  822.  
  823. int needmousehack()
  824. {
  825.     return 1;
  826. }
  827.  
  828. void LED(int on)
  829. {
  830. }
  831.  
  832. void parse_cmdline ()
  833. {
  834.     /* No commandline on the Mac. */
  835. }
  836.  
  837. static void PStrCat ( StringPtr p1, StringPtr p2)
  838. {
  839.     register int len;
  840.     register int total;
  841.     StringPtr    p3;
  842.     
  843.     len = *p1++;
  844.     total = len +*p2;
  845.     
  846.     p3=p2;
  847.     p2=p2+ (*p2 + 1);
  848.     
  849.     while (--len>=0) *p2++=*p1++;
  850.     *p3=total;
  851. }
  852.  
  853. static void PStrCopy ( StringPtr p1, StringPtr p2)
  854. {
  855.     register int len;
  856.     
  857.     len = *p2++ = *p1++;
  858.     while (--len>=0) *p2++=*p1++;
  859. }
  860.  
  861. short vRefNum=0;
  862. long dirID=0;
  863.  
  864. static void HandleMenu (long mSelect)
  865. {    short        menuID;
  866.     short        menuItem;
  867.     Str32        name;
  868.     GrafPtr        savePort;
  869.     WindowPtr    batchWin;
  870.     Str255        batchStr,batchStr2;
  871.     StandardFileReply        inputReply;
  872.     char        strSize,i;
  873.     long        count;
  874.     FILE        *outFile;
  875.     char        fileBuf[512];
  876.     int            backup=0;
  877.  
  878.     menuID = HiWord(mSelect);
  879.     menuItem = LoWord(mSelect);
  880.  
  881.     if (menuID == 0) return;
  882.     switch (menuID)
  883.     {    case kAppleMenuID:
  884.               if (menuItem == 1)
  885.               {    if (!macCursorState) ShowCursor();
  886.                 macCursorState=true;
  887.                   Alert(kAboutDialogID,0); // About Box
  888.                   if (dont_want_aspect || screen_res == 2) printStatusLine();
  889.               }
  890.              else
  891.              {    GetPort(&savePort);
  892.                  GetItem(GetMenuHandle(kAppleMenuID), menuItem, name);
  893.                 OpenDeskAcc(name);
  894.                 SystemTask();
  895.                 SetPort(savePort);
  896.             }
  897.             break;
  898.          
  899.          case kFileMenuID:
  900.             switch (menuItem)
  901.             {    case 1:
  902.                     m68k_reset();
  903.                 break;
  904.                 
  905.                 case 3:
  906.                     if (dont_want_aspect == 0)
  907.                     {    if (mBarState) HideMenuBar(mywin);
  908.                         else ShowMenuBar(mywin);
  909.                         mBarState=!mBarState;
  910.                     }
  911.                 break;
  912.                 
  913.                 case 5:
  914.                             activate_debugger();
  915.                 break;
  916.                 
  917.                 case 7:
  918.                     inhibit_frame ^= 1;
  919.                     if (inhibit_frame) SetMenuItemText(GetMenuHandle(kFileMenuID), 7, "\pTurn Screen Update On");
  920.                     else SetMenuItemText(GetMenuHandle(kFileMenuID), 7, "\pTurn Screen Update Off");
  921.                 break;
  922.                 
  923.                 case 9:
  924.                     produce_sound= !produce_sound;
  925.                     if (produce_sound) SetMenuItemText(GetMenuHandle(kFileMenuID), 9, "\pTurn Sound Off");
  926.                     else SetMenuItemText(GetMenuHandle(kFileMenuID), 9, "\pTurn Sound On");
  927.                     WritePrefs(0);
  928.                 break;
  929.                 
  930.                 case 11:
  931.                     fake_joystick= !fake_joystick;
  932.                     if (fake_joystick) SetMenuItemText(GetMenuHandle(kFileMenuID), 11, "\pTurn Joystick Off");
  933.                     else SetMenuItemText(GetMenuHandle(kFileMenuID), 11, "\pTurn Joystick On");
  934.                     WritePrefs(0);
  935.                 break;
  936.                 
  937.                 case 13:
  938.                     broken_in = 1;
  939.                     regs.spcflags |= SPCFLAG_BRK;
  940.                     quit_program=1;
  941.                 break;
  942.             }
  943.             break;
  944.         
  945.         case kDrivesMenuID:
  946.             if (menuItem >= 1 && menuItem <= 4)
  947.             {    if (macDiskStatus[menuItem-1]) disk_eject(menuItem-1);
  948.                     else
  949.                     {    if (!macCursorState) ShowCursor();
  950.                         if (!mBarState) ShowMenuBar(mywin);
  951.                         macCursorState=true;
  952.                         StandardGetFile(nil,-1L,nil,&inputReply);
  953.                         if (inputReply.sfGood)
  954.                         {    vRefNum=inputReply.sfFile.vRefNum;
  955.                             dirID=inputReply.sfFile.parID;
  956.                             disk_insert (menuItem-1, p2cstr(inputReply.sfFile.name));
  957.                         }
  958.                         else macDiskStatus[menuItem-1] = !macDiskStatus[menuItem-1];
  959.                         if (!mBarState) HideMenuBar(mywin);
  960.                     }
  961.                     macDiskStatus[menuItem-1] = !macDiskStatus[menuItem-1];
  962.                     if (macDiskStatus[menuItem-1]) PStrCopy("\pEject Disk in DF",batchStr);
  963.                     else PStrCopy("\pInsert Disk in DF",batchStr);
  964.                     NumToString((long)(menuItem-1),batchStr2);
  965.                     PStrCat(batchStr2,batchStr);
  966.                     PStrCat("\p:",batchStr);
  967.                     SetMenuItemText(GetMenuHandle(kDrivesMenuID), menuItem, batchStr);
  968.         
  969.             }
  970.             if (menuItem == 6)
  971.             {    if (!macCursorState) ShowCursor();
  972.                 macCursorState=true;
  973.                 for (count=0;count<512;count++) fileBuf[count]=0;
  974.                 errno=0;
  975.                 outFile=fopen("hardfile","wb");
  976.                 if (outFile != 0)
  977.                 {    for (count=0;count<16384;count++)
  978.                     {    fwrite(fileBuf, sizeof(char), 512, outFile);
  979.                         if (errno != 0)
  980.                         {    ParamAString("\pError generating the hardfile!.\n Make sure you have at least 8Mb of free storage on your Harddrive.");
  981.                             DisplayError(kQuitError);
  982.                         }
  983.                     }
  984.                     fclose(outFile);
  985.                     Alert(kHardfileDialogID,0);
  986.                 }
  987.                 else
  988.                 {    ParamAString("\pCan't create the hardfile!.\n Make sure your Harddrive isnt either software or hardware locked.");
  989.                     DisplayError(kQuitError);
  990.                 }
  991.             }
  992.             if (menuItem == 7)
  993.             {    my_automount_uaedev=!my_automount_uaedev;
  994.                 WritePrefs(0);
  995.                 ParamAString("\pChanges will take effect the next time you run UAE.");
  996.                 DisplayError(kQuitError);
  997.                 CheckItem(GetMenuHandle(kDrivesMenuID),7,my_automount_uaedev ? false : true);
  998.             }
  999.             if (menuItem == 9)
  1000.             {    if (!macCursorState) ShowCursor();
  1001.                 macCursorState=true;
  1002.                 Share_main();
  1003.             }
  1004.         break;
  1005.         
  1006.         case kMemoryMenuID:
  1007.             if (menuItem == 1) use_slow_mem = !use_slow_mem;
  1008.             WritePrefs(0);
  1009.             ParamAString("\pChanges will take effect the next time you run UAE.");
  1010.             DisplayError(kQuitError);
  1011.             if (use_slow_mem) SetMenuItemText(GetMenuHandle(kMemoryMenuID), 1, "\pDisable 1 Mb (SlowMem)");
  1012.             else SetMenuItemText(GetMenuHandle(kMemoryMenuID), 1, "\pEnable 1 Mb (SlowMem)");
  1013.         break;
  1014.             
  1015.         case kResMenuID:
  1016.             my_screen_res=(int)menuItem-1;
  1017.             WritePrefs(0);
  1018.             CheckItem(GetMenuHandle(kResMenuID),screen_res+1,false);
  1019.             CheckItem(GetMenuHandle(kResMenuID),my_screen_res+1,true);
  1020.             ParamAString("\pChanges will take effect the next time you run UAE.");
  1021.             DisplayError(kQuitError);
  1022.         break;
  1023.         
  1024.         case kRateMenuID:
  1025.             for (count=1;count<5;count++) CheckItem(GetMenuHandle(kRateMenuID),count,false);
  1026.             if (menuItem == 1) framerate=1;
  1027.             if (menuItem == 2) framerate=3;
  1028.             if (menuItem == 3) framerate=5;
  1029.             if (menuItem == 4) framerate=7;
  1030.             CheckItem(GetMenuHandle(kRateMenuID),menuItem,true);
  1031.             WritePrefs(0);
  1032.         break;
  1033.         
  1034.         case kVideoMenuID:
  1035.         if (menuItem == 5)
  1036.         {    my_use_quickdraw = !my_use_quickdraw;
  1037.             WritePrefs(0);
  1038.             CheckItem(GetMenuHandle(kVideoMenuID),5,my_use_quickdraw ? true : false);
  1039.             ParamAString("\pChanges will take effect the next time you run UAE.");
  1040.             DisplayError(kQuitError);
  1041.         }
  1042.         if (menuItem == 7)
  1043.         {    my_use_gfxlib = !my_use_gfxlib;
  1044.             WritePrefs(0);
  1045.             CheckItem(GetMenuHandle(kVideoMenuID),7,my_use_gfxlib ? true : false);
  1046.             ParamAString("\pChanges will take effect the next time you run UAE.");
  1047.             DisplayError(kQuitError);
  1048.         }
  1049.         break;
  1050.         
  1051.         default:
  1052.             break;
  1053.     }
  1054.     HiliteMenu(0);
  1055.     flush_screen();
  1056.     if (dont_want_aspect  || screen_res == 2) printStatusLine();
  1057. }
  1058.  
  1059. static void macHandleCursors(void)
  1060. {    Point    mpos;
  1061.  
  1062.     if (redraw)
  1063.     {    GetMouse(&mpos);
  1064.         if (!dont_want_aspect && mBarState && screen_res == 4)
  1065.         {    if (mpos.v < 20)
  1066.             {    ShowCursor();
  1067.                 macCursorState=true;
  1068.             }
  1069.             else
  1070.             {    if (macCursorState)
  1071.                 {    HideCursor();
  1072.                     macCursorState=false;
  1073.                 }
  1074.             }
  1075.         }
  1076.         else
  1077.         if (PtInRect(mpos,&(mywin->portRect)))
  1078.         {    if (macCursorState)
  1079.             {    HideCursor();
  1080.                 macCursorState=false;
  1081.             }
  1082.         }
  1083.         else
  1084.         {    if (!macCursorState)
  1085.             {    ShowCursor();
  1086.                 macCursorState=true;
  1087.             }
  1088.         }
  1089.     }
  1090. }
  1091.  
  1092. // Check Minimal System Configuration and Setup
  1093. static Boolean CheckForSetup (void)
  1094. {    Boolean            retvalue=false;
  1095.     SysEnvRec        env;
  1096.     
  1097.     oldDepth=0;
  1098.     SysEnvirons( 2, &env );
  1099.     
  1100.     if ( env.systemVersion < 0x0700 )
  1101.     {    ParamAString("\pUAE requires System 7 or later!\n Press Ok to Quit...");
  1102.         DisplayError(kQuitError);
  1103.         retvalue=true;
  1104.     }
  1105.     if ( !env.hasColorQD)
  1106.     {    ParamAString("\pUAE requires Color QuickDraw!\n Press Ok to Quit...");
  1107.         DisplayError(kQuitError);
  1108.         retvalue=true;
  1109.     }
  1110.     curDevice = GetMainDevice();
  1111.     gfxvidinfo.pixbytes=((*(*curDevice)->gdPMap)->pixelSize)/8;
  1112.     return(retvalue);
  1113. }
  1114.  
  1115. // Shows up the standard error alert;
  1116. static int DisplayError(int ID)
  1117. {    int    ret=0;
  1118.  
  1119.     InitCursor();
  1120.     ret=Alert(ID,0);
  1121.  
  1122.     return (ret);
  1123. }
  1124.  
  1125. // Parses a Pascal string for error display
  1126. static void ParamAString( ConstStr255Param theStr )
  1127. {
  1128.     ParamText(theStr, "\p", "\p", "\p");
  1129. }
  1130.  
  1131. static void printStatusLine (void)
  1132. {    GrafPtr savePort;
  1133.     Rect    updateRect;
  1134.  
  1135.     updateRect.top=screenV;
  1136.     updateRect.bottom=screenV+38;
  1137.     updateRect.left=0;
  1138.     updateRect.right=screenH;
  1139.     GetPort(&savePort);
  1140.     SetPort(mywin);
  1141.     EraseRect(&updateRect);
  1142.     MoveTo(10,screenV+10);
  1143.     TextFont(monaco);
  1144.     TextSize(9);
  1145.     if (screen_res >= 3)
  1146.     DrawString("\pPower LED:        Drive LEDs:  DF0:        DF1:        DF2:        DF3:");
  1147.     else DrawString("\pPower:      DF0:      DF1:      DF2:      DF3:");
  1148.     TextFont(0);
  1149.      TextSize(0);
  1150.      SetPort(savePort);
  1151. }
  1152.  
  1153. typedef struct {
  1154.     StandardFileReply *replyPtr;
  1155.     FSSpec oldSelection;
  1156. } SFData, *SFDataPtr;
  1157.  
  1158. /* constants */
  1159.  
  1160. #define    kSelectItem            10
  1161. #define    kSFDlg                128
  1162. #define    kCanSelectDesktop    true
  1163. #define    kSelectStrRsrc        128
  1164. #define kDefaultSelectString "\pSelect"
  1165. #define    kDeskStrRsrc        129
  1166. #define    kDefaultDeskString    "\pDesktop"
  1167. #define    kSelectKey            's'
  1168.  
  1169. /* globals */
  1170.  
  1171. Boolean gHasFindFolder;
  1172. FSSpec gDeskFolderSpec;
  1173. Str255 gSelectString;
  1174. Str255 gDesktopFName;
  1175.  
  1176. FileFilterYDUPP Share_FilterAllFiles_UPP;
  1177. DlgHookYDUPP Share_MyDlgHook_UPP;
  1178. ModalFilterYDUPP Share_MyModalFilter_UPP;
  1179.  
  1180. /* prototypes */
  1181.  
  1182. static void Share_Init(void);
  1183. static Boolean Share_CustomGet(FSSpec *fSpec);
  1184. static pascal short Share_MyDlgHook(short item,DialogPtr theDlg,Ptr userData);
  1185. static pascal Boolean Share_MyModalFilter(DialogPtr theDlg,EventRecord *ev,short *itemHit,Ptr myData);
  1186. static void Share_HitButton(DialogPtr theDlg,short item);
  1187. static pascal Boolean Share_FilterAllFiles(CInfoPBPtr pb, Ptr myDataPtr);
  1188. static void Share_SetSelectButtonName(StringPtr selName,Boolean hilited,DialogPtr theDlg);
  1189. static Boolean Share_SameFile(FSSpec *file1,FSSpec *file2);
  1190. static Boolean Share_GetFSSpecPartialName(FSSpec *file,StringPtr fName);
  1191. static OSErr Share_GetDeskFolderSpec(FSSpec *fSpec,short vRefNum);
  1192. static OSErr Share_MakeCanonFSSpec(FSSpec *fSpec);
  1193. static Boolean Share_ShouldHiliteSelect(FSSpec *fSpec);
  1194.  
  1195.  
  1196. static void Share_main(void)
  1197. {    FSSpec fSpec;
  1198.     Boolean good;
  1199.     GrafPtr oldPort;
  1200.     char share_path[1024];
  1201.     Handle    share_handle;
  1202.     short backup;
  1203.     
  1204.     GetPort(&oldPort);
  1205.     Share_Init();
  1206.     
  1207.     good = Share_CustomGet(&fSpec);
  1208.     
  1209.     if (good)
  1210.     {    Share_ResolvePath(&fSpec,share_path);
  1211.         backup=filesys_vRefNum;
  1212.         filesys_vRefNum=fSpec.vRefNum;
  1213.         WritePrefs(share_path);
  1214.         filesys_vRefNum=backup;
  1215.     }
  1216.     SetPort(oldPort);
  1217. }
  1218.  
  1219. static void Share_Init(void)
  1220. {
  1221.     Handle strHndl;
  1222.     
  1223.     gHasFindFolder = true;
  1224.     
  1225.     Share_FilterAllFiles_UPP=NewFileFilterYDProc(Share_FilterAllFiles);
  1226.     Share_MyDlgHook_UPP=NewDlgHookYDProc(Share_MyDlgHook);
  1227.     Share_MyModalFilter_UPP=NewModalFilterYDProc(Share_MyModalFilter);
  1228.     
  1229.     strHndl = Get1Resource('STR ',kSelectStrRsrc);
  1230.     if (ResError()!=noErr || !strHndl || !*strHndl)
  1231.         BlockMove(kDefaultSelectString,gSelectString,kDefaultSelectString[0]+1);
  1232.     else {
  1233.         BlockMove(*strHndl,&gSelectString,(long)((unsigned char *)(*strHndl)[0]+1));
  1234.         ReleaseResource(strHndl);
  1235.     }
  1236.  
  1237.     strHndl = Get1Resource('STR ',kDeskStrRsrc);
  1238.     if (ResError()!=noErr || !strHndl || !*strHndl)
  1239.         BlockMove(kDefaultDeskString,gDesktopFName,kDefaultSelectString[0]+1);
  1240.     else {
  1241.         BlockMove(*strHndl,&gDesktopFName,(long)((unsigned char *)(*strHndl)[0]+1));
  1242.         ReleaseResource(strHndl);
  1243.     }
  1244. }
  1245.  
  1246.  
  1247. /* do getfile */
  1248.  
  1249. static Boolean Share_CustomGet(FSSpec *fSpec)
  1250. {
  1251.     Point where = {-1,-1};
  1252.     SFReply reply;
  1253.     DialogPtr theDialog;
  1254.     short item;
  1255.     StandardFileReply sfReply;
  1256.     SFData sfUserData;
  1257.     OSErr err;
  1258.     Boolean targetIsFolder,wasAliased;
  1259.     
  1260.     /* initialize user data area */
  1261.     
  1262.     sfUserData.replyPtr = &sfReply;
  1263.     sfUserData.oldSelection.vRefNum = -9999;    /* init to ridiculous value */
  1264.     
  1265.     CustomGetFile(Share_FilterAllFiles_UPP,-1,nil,&sfReply,kSFDlg,where,Share_MyDlgHook_UPP,
  1266.                     Share_MyModalFilter_UPP,nil,nil,&sfUserData);
  1267.     
  1268.     if (sfReply.sfGood) {
  1269.         err = ResolveAliasFile(&sfReply.sfFile,true,&targetIsFolder,&wasAliased);
  1270.         if (err!=noErr)
  1271.             return false;
  1272.     }
  1273.     
  1274.     err = FSMakeFSSpec(sfReply.sfFile.vRefNum,sfReply.sfFile.parID,sfReply.sfFile.name,fSpec);
  1275.     if (err!=noErr)
  1276.         return false;
  1277.     
  1278.     return sfReply.sfGood;
  1279. }
  1280.  
  1281. static pascal short Share_MyDlgHook(short item,DialogPtr theDlg,Ptr userData)
  1282. {
  1283.     SFDataPtr sfUserData;
  1284.     Boolean hiliteButton;
  1285.     FSSpec curSpec;
  1286.     OSType refCon;
  1287.     
  1288.     refCon = GetWRefCon(theDlg);
  1289.     if (refCon!=sfMainDialogRefCon)
  1290.         return item;
  1291.         
  1292.     sfUserData = (SFDataPtr) userData;
  1293.     
  1294.     if (item==sfHookFirstCall || item==sfHookLastCall)
  1295.         return item;
  1296.     
  1297.     if (item==sfItemVolumeUser) {
  1298.         sfUserData->replyPtr->sfFile.name[0] = '\0';
  1299.         sfUserData->replyPtr->sfFile.parID = 2;
  1300.         sfUserData->replyPtr->sfIsFolder = false;
  1301.         sfUserData->replyPtr->sfIsVolume = false;
  1302.         sfUserData->replyPtr->sfFlags = 0;
  1303.         item = sfHookChangeSelection;
  1304.     }
  1305.         
  1306.     if (!Share_SameFile(&sfUserData->replyPtr->sfFile,&sfUserData->oldSelection)) {
  1307.         BlockMove(&sfUserData->replyPtr->sfFile,&curSpec,sizeof(FSSpec));
  1308.         Share_MakeCanonFSSpec(&curSpec);
  1309.         
  1310.         if (curSpec.vRefNum!=sfUserData->oldSelection.vRefNum)
  1311.             Share_GetDeskFolderSpec(&gDeskFolderSpec,curSpec.vRefNum);    
  1312.         Share_SetSelectButtonName(curSpec.name,Share_ShouldHiliteSelect(&curSpec),theDlg);
  1313.         
  1314.         BlockMove(&sfUserData->replyPtr->sfFile,&sfUserData->oldSelection,sizeof(FSSpec));
  1315.     }
  1316.     
  1317.     if (item==kSelectItem)
  1318.         item = sfItemOpenButton;
  1319.         
  1320.     return item;
  1321. }
  1322.  
  1323.  
  1324. static pascal Boolean Share_MyModalFilter(DialogPtr theDlg,EventRecord *ev,short *itemHit,Ptr myData)
  1325. {
  1326.     Boolean evHandled;
  1327.     char keyPressed;
  1328.     OSType refCon;
  1329.     
  1330.     refCon = GetWRefCon(theDlg);
  1331.     if (refCon!=sfMainDialogRefCon)
  1332.         return false;
  1333.         
  1334.     evHandled = false;
  1335.     
  1336.     switch (ev->what) {
  1337.         case keyDown:
  1338.         case autoKey:
  1339.             keyPressed = ev->message & charCodeMask;
  1340.             if ((ev->modifiers & cmdKey) != 0) {
  1341.                 switch (keyPressed) {
  1342.                     case kSelectKey:
  1343.                         Share_HitButton(theDlg,kSelectItem);
  1344.                         *itemHit = kSelectItem;
  1345.                         evHandled = true;
  1346.                         break;
  1347.                 }
  1348.             }
  1349.             break;
  1350.     }
  1351.     
  1352.     return evHandled;
  1353. }
  1354.  
  1355.  
  1356. static void Share_HitButton(DialogPtr theDlg,short item)
  1357. {
  1358.     short iType;
  1359.     Handle iHndl;
  1360.     Rect iRect;
  1361.     long fTicks;
  1362.     
  1363.     GetDItem(theDlg,item,&iType,&iHndl,&iRect);
  1364.     HiliteControl((ControlHandle)iHndl,inButton);
  1365.     Delay(5,&fTicks);
  1366.     HiliteControl((ControlHandle)iHndl,0);
  1367. }
  1368.  
  1369.  
  1370. static pascal Boolean Share_FilterAllFiles(CInfoPBPtr pb, Ptr myDataPtr)
  1371. {
  1372.     if (pb->hFileInfo.ioFlAttrib & (1<<4))    /* file is a directory */
  1373.         return false;
  1374.  
  1375.     return true;
  1376. }
  1377.  
  1378.  
  1379. static void Share_SetSelectButtonName(StringPtr selName,Boolean hilited,DialogPtr theDlg)
  1380. {
  1381.     ControlHandle selectButton;
  1382.     short iType;
  1383.     Handle iHndl;
  1384.     Rect iRect;
  1385.     Str255 storeName,tempLenStr,tempSelName;
  1386.     short btnWidth;
  1387.     
  1388.     BlockMove(selName,tempSelName,selName[0]+1);
  1389.     GetDItem(theDlg,kSelectItem,&iType,&iHndl,&iRect);
  1390.     
  1391.     /* truncate select name to fit in button */
  1392.     
  1393.     btnWidth = iRect.right - iRect.left;
  1394.     BlockMove(gSelectString,tempLenStr,gSelectString[0]+1);
  1395.     p2cstr(tempLenStr);
  1396.     strcat((char *)tempLenStr," ÒÓ  ");
  1397.     c2pstr((char *)tempLenStr);
  1398.     btnWidth -= StringWidth(tempLenStr);
  1399.     TruncString(btnWidth,tempSelName,smTruncMiddle);
  1400.     
  1401.     BlockMove(gSelectString,storeName,gSelectString[0]+1);
  1402.     p2cstr(storeName);
  1403.     p2cstr(tempSelName);
  1404.     strcat((char *)storeName," Ò");
  1405.     strcat((char *)storeName,(char *)tempSelName);
  1406.     strcat((char *)storeName,"Ó");
  1407.     
  1408.     c2pstr((char *)storeName);
  1409.     c2pstr((char *)tempSelName);
  1410.     SetCTitle((ControlHandle)iHndl,storeName);
  1411.     
  1412.     SetDItem(theDlg,kSelectItem,iType,iHndl,&iRect);
  1413.  
  1414.     if (hilited)
  1415.         HiliteControl((ControlHandle)iHndl,0);
  1416.     else
  1417.         HiliteControl((ControlHandle)iHndl,255);        
  1418. }
  1419.  
  1420.  
  1421. static Boolean Share_SameFile(FSSpec *file1,FSSpec *file2)
  1422. {
  1423.     if (file1->vRefNum != file2->vRefNum)
  1424.         return false;
  1425.     if (file1->parID != file2->parID)
  1426.         return false;
  1427.     if (!EqualString(file1->name,file2->name,false,true))
  1428.         return false;
  1429.     
  1430.     return true;
  1431. }
  1432.  
  1433.  
  1434. static OSErr Share_GetDeskFolderSpec(FSSpec *fSpec,short vRefNum)
  1435. {
  1436.     DirInfo infoPB;
  1437.     OSErr err;
  1438.     
  1439.     if (!gHasFindFolder) {
  1440.         fSpec->vRefNum = -9999;
  1441.         return -1;
  1442.     }
  1443.     
  1444.     fSpec->name[0] = '\0';
  1445.     err = FindFolder(vRefNum,kDesktopFolderType,kDontCreateFolder,
  1446.                         &fSpec->vRefNum,&fSpec->parID);
  1447.     if (err!=noErr)
  1448.         return err;
  1449.     
  1450.     return Share_MakeCanonFSSpec(fSpec);
  1451. }
  1452.  
  1453.  
  1454. static Boolean Share_ShouldHiliteSelect(FSSpec *fSpec)
  1455. {
  1456.     if (Share_SameFile(fSpec,&gDeskFolderSpec)) {
  1457.         BlockMove(gDesktopFName,fSpec->name,gDesktopFName[0]+1);
  1458.         return kCanSelectDesktop;
  1459.     }
  1460.     else
  1461.         return true;
  1462. }
  1463.  
  1464. static OSErr Share_MakeCanonFSSpec(FSSpec *fSpec)
  1465. {
  1466.     CInfoPBRec infoPB;
  1467.     OSErr err;
  1468.  
  1469.     if (fSpec->name[0] != '\0')
  1470.         return;
  1471.         
  1472.     infoPB.dirInfo.ioNamePtr = fSpec->name;
  1473.     infoPB.dirInfo.ioVRefNum = fSpec->vRefNum;
  1474.     infoPB.dirInfo.ioDrDirID = fSpec->parID;
  1475.     infoPB.dirInfo.ioFDirIndex = -1;
  1476.     err = PBGetCatInfo(&infoPB,false);
  1477.     fSpec->parID = infoPB.dirInfo.ioDrParID;
  1478.     
  1479.     return err;
  1480. }
  1481.  
  1482. static void Share_ResolvePath (FSSpec *fSpec, char *path)
  1483. {    char volname[128];
  1484.     char dirname[128];
  1485.     char path_copy[1024];
  1486.     short the_vRefNum;
  1487.     long  the_parID;
  1488.     CInfoPBRec infoPB;
  1489.  
  1490.     volname[0]=0;
  1491.     strcpy(dirname,(char *)fSpec->name);
  1492.     p2cstr((unsigned char *)dirname);
  1493.     
  1494.     strcpy(path,dirname);
  1495.     
  1496.     the_vRefNum=(fSpec->vRefNum);
  1497.     the_parID=(fSpec->parID);
  1498.  
  1499.     infoPB.dirInfo.ioNamePtr = (unsigned char *)volname;
  1500.     infoPB.dirInfo.ioVRefNum = the_vRefNum;
  1501.     infoPB.dirInfo.ioDrDirID = fsRtDirID;
  1502.     infoPB.dirInfo.ioFDirIndex = -1;
  1503.     PBGetCatInfo(&infoPB,false);
  1504.  
  1505.     p2cstr((unsigned char *)volname);
  1506.  
  1507.     while (strcmp(volname,dirname) != 0)
  1508.     {        
  1509.         infoPB.dirInfo.ioNamePtr = (unsigned char *)dirname;
  1510.         infoPB.dirInfo.ioVRefNum = the_vRefNum;
  1511.         infoPB.dirInfo.ioDrDirID = the_parID;
  1512.         infoPB.dirInfo.ioFDirIndex = -1;
  1513.         PBGetCatInfo(&infoPB,false);
  1514.         the_parID = infoPB.dirInfo.ioDrParID;
  1515.     
  1516.         p2cstr((unsigned char *)dirname);
  1517.         strcpy(path_copy,dirname);
  1518.         strcat(path_copy,":");
  1519.         strcat(path_copy,path);
  1520.         strcpy(path,path_copy);
  1521.     }
  1522. }
  1523.  
  1524. Boolean ReadPrefs (char *share_path)
  1525. {    OSErr err=noErr;
  1526.     short prefsFolder;
  1527.     Str255 prefsName="\pUAE Preferences";
  1528.     long prefDirID;
  1529.     short prefvRefNum;
  1530.     FSSpec spec;
  1531.     short home,preffile;
  1532.     Handle share_handle;
  1533.     Handle config_handle;
  1534.     int config_sets[128],count;
  1535.  
  1536.     home = CurResFile();
  1537.     preffile=0;
  1538.     *share_path=0;
  1539.     
  1540.     err=FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &prefvRefNum, &prefDirID);
  1541.     if (err != noErr) return false;
  1542.     FSMakeFSSpec(prefvRefNum, prefDirID, prefsName, &spec);
  1543.  
  1544.     preffile=FSpOpenResFile(&spec, fsRdWrPerm);
  1545.     if (ResError() != noErr) return false;
  1546.  
  1547.     UseResFile(preffile);
  1548.  
  1549.     if (share_path != 0)
  1550.     {    share_handle = Get1Resource('STR ',128);
  1551.         if (ResError() == noErr && share_handle !=0 && *share_handle !=0)
  1552.         {    strcpy(share_path,*share_handle);
  1553.             ReleaseResource(share_handle);
  1554.         }
  1555.     }
  1556.  
  1557.     config_handle = Get1Resource('PREF',128);
  1558.     if (ResError() == noErr && config_handle !=0)
  1559.     {    BlockMove((Ptr) *config_handle,(Ptr) config_sets,128);
  1560.         ReleaseResource(config_handle);
  1561.         
  1562.         framerate=config_sets[0];
  1563.         use_slow_mem=config_sets[1];
  1564.         use_gfxlib=config_sets[2];
  1565.         automount_uaedev=config_sets[3];
  1566.         produce_sound=config_sets[4];
  1567.         fake_joystick=config_sets[5];
  1568.         screen_res=config_sets[6];
  1569.         use_quickdraw=config_sets[7];
  1570.         filesys_vRefNum=config_sets[8];
  1571.     }
  1572.  
  1573.     UseResFile(home);
  1574.     CloseResFile(preffile);
  1575.     return true;
  1576. }
  1577.  
  1578. void CreatePrefs (void)
  1579. {    OSErr err=noErr;
  1580.     short prefsFolder;
  1581.     Str255 prefsName="\pUAE Preferences";
  1582.     long prefDirID;
  1583.     short prefvRefNum;
  1584.     FSSpec spec;
  1585.     short home,preffile;
  1586.     
  1587.     home = CurResFile();
  1588.     preffile=0;
  1589.     
  1590.     err=FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &prefvRefNum, &prefDirID);
  1591.     if (err != noErr) return;
  1592.     FSMakeFSSpec(prefvRefNum, prefDirID, prefsName, &spec);
  1593.     
  1594.     err=FSpCreate(&spec, 'mUAE', 'pref', 0);
  1595.     if (err != noErr) return;
  1596.     
  1597.     FSpCreateResFile(&spec, 'mUAE', 'pref', 0);
  1598. }
  1599.  
  1600. void WritePrefs (char *share_path)
  1601. {    OSErr err=noErr;
  1602.     short prefsFolder;
  1603.     Str255 prefsName="\pUAE Preferences";
  1604.     long prefDirID;
  1605.     short prefvRefNum;
  1606.     FSSpec spec;
  1607.     short home,preffile;
  1608.     Handle share_handle;
  1609.     Handle config_handle;
  1610.     int config_sets[128],count;
  1611.     
  1612.     home = CurResFile();
  1613.     preffile=0;
  1614.     
  1615.     err=FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &prefvRefNum, &prefDirID);
  1616.     if (err != noErr) return;
  1617.     FSMakeFSSpec(prefvRefNum, prefDirID, prefsName, &spec);
  1618.     
  1619.     preffile=FSpOpenResFile(&spec, fsRdWrPerm);
  1620.     if (ResError() != noErr) return;
  1621.     
  1622.     for (count=0;count < 64;count++) config_sets[count]=0;
  1623.     
  1624.     config_sets[0]=framerate;
  1625.     config_sets[1]=use_slow_mem;
  1626.     config_sets[2]=my_use_gfxlib;
  1627.     config_sets[3]=my_automount_uaedev;
  1628.     config_sets[4]=produce_sound;
  1629.     config_sets[5]=fake_joystick;
  1630.     config_sets[6]=my_screen_res;
  1631.     config_sets[7]=my_use_quickdraw;
  1632.     config_sets[8]=filesys_vRefNum;
  1633.     
  1634.     UseResFile(preffile);
  1635.     
  1636.     
  1637.     if (share_path != 0)
  1638.     {    share_handle=Get1Resource('STR ',128);
  1639.         if (ResError() != noErr || share_handle == 0)
  1640.         {    share_handle=NewHandleClear(1024);
  1641.             strcpy(*share_handle,share_path);
  1642.             AddResource(share_handle,'STR ',128, "\pMac/Amiga sharing path");
  1643.             WriteResource(share_handle);
  1644.             DetachResource(share_handle);
  1645.         }
  1646.         else
  1647.         {    strcpy(*share_handle,share_path);
  1648.             ChangedResource(share_handle);
  1649.             WriteResource(share_handle);
  1650.             ReleaseResource(share_handle);
  1651.         }
  1652.     }
  1653.     
  1654.     config_handle=Get1Resource('PREF',128);
  1655.     if (ResError() != noErr || config_handle == 0)
  1656.     {    config_handle=NewHandleClear(1024);
  1657.         BlockMove((Ptr) config_sets,(Ptr) *config_handle,128);
  1658.         AddResource(config_handle,'PREF',128, "\pUAE Preferences");
  1659.         WriteResource(config_handle);
  1660.         DetachResource(config_handle);
  1661.     }
  1662.     else
  1663.     {    BlockMove((Ptr) config_sets,(Ptr) *config_handle,128);
  1664.         ChangedResource(config_handle);
  1665.         WriteResource(config_handle);
  1666.         ReleaseResource(config_handle);
  1667.     }
  1668.     
  1669.     UseResFile(home);
  1670.     CloseResFile(preffile);
  1671. }
  1672.